package com.dailyyoga.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class EditImageView extends ImageView implements OnTouchListener {

	int sideWith = 0;
	int sideHeight = 0;
	Matrix _matrix = new Matrix();
	Matrix _savedMatrix = new Matrix();
	Matrix _tmpMatrix = new Matrix();
	DisplayMetrics _dm;
	EditImageView _imgView;
	Bitmap _bitmap;
	float minScaleR;// ��С���ű���
	static final float MAX_SCALE = 4f;// ������ű���
	static final int NONE = 0;// ��ʼ״̬
	static final int DRAG = 1;// �϶�
	static final int ZOOM = 2;// ����
	int mode = NONE;

	PointF prev = new PointF();
	PointF mid = new PointF();
	float dist = 1f;
	float k;

	public EditImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		setOnTouchListener(this);
	}

	public EditImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		setOnTouchListener(this);
	}

	public EditImageView(Context context) {
		super(context);
		setOnTouchListener(this);

	}

	protected void onDraw(Canvas canvas) {

		super.onDraw(canvas);

		drawSide(canvas);
	}

	protected void onSizeChanged(int w, int h, int oldw, int oldh) {

		if (w > 400 && h > 400) {
			sideHeight = 400;
			sideWith = 400;
		} else if (w > 300 && h > 300) {
			sideHeight = 300;
			sideWith = 300;
		} else {
			sideHeight = 200;
			sideWith = 200;
		}
		fixLayout(_fixView);
		super.onSizeChanged(w, h, oldw, oldh);

		if (_bitmap != null) {
			rotateBitMap(_degrees);
		}

	}

	View _fixView;

	public void fixLayout(View view) {

		if (view == null) {
			return;
		}

		_fixView = view;

		if (sideHeight == 0 || sideWith == 0) {
			return;
		}

		postDelayed(new Runnable() {

			public void run() {
				LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) _fixView.getLayoutParams();
				layoutParams.width = sideWith;
				layoutParams.height = sideHeight;

				LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(
						layoutParams.width, layoutParams.height);

				ViewGroup group = (ViewGroup) _fixView.getParent();
				group.removeView(_fixView);
				group.addView(_fixView, 1, layoutParams2);
				System.out.println("fixLayout w=" + layoutParams.width + " h="
						+ layoutParams.height);

			}
		}, 10);

	}

	private void rotateBitMap(int rotateDegrees) {

		if (_bitmap == null) {
			return;
		}

		_matrix.reset();

		if (_bitmap.getWidth() <= sideWith && _bitmap.getHeight() <= sideWith) {
			_scale = Scale.small;
		} else if (_bitmap.getWidth() <= getWidth()
				&& _bitmap.getHeight() <= getHeight()) {
			_scale = Scale.large;
		} else {
			_scale = Scale.xlarge;
		}

		if (rotateDegrees == 0) {

			if (_scale != Scale.xlarge) {
				k = 1;
			} else {
				k = getWidth() * 1.0f / getHeight() > _bitmap.getWidth() * 1.0f
						/ _bitmap.getHeight() * 1.0f ? getHeight() * 1.0f
						/ _bitmap.getHeight() : getWidth() * 1.0f
						/ _bitmap.getWidth();
			}

			_matrix.postScale(k, k);
			_matrix.postRotate(rotateDegrees, _bitmap.getWidth() * k / 2f,
					_bitmap.getHeight() * k / 2f);

			_matrix.postTranslate((getWidth() - _bitmap.getWidth() * k) / 2,
					(getHeight() - _bitmap.getHeight() * k) / 2);

		} else if (rotateDegrees == 180) {

			if (_scale != Scale.xlarge) {
				k = 1;
			} else {

				k = getWidth() * 1.0f / getHeight() > _bitmap.getWidth() * 1.0f
						/ _bitmap.getHeight() * 1.0f ? getHeight() * 1.0f
						/ _bitmap.getHeight() : getWidth() * 1.0f
						/ _bitmap.getWidth();
			}

			_matrix.postScale(k, k);
			_matrix.postRotate(rotateDegrees);
			_matrix.postTranslate(_bitmap.getWidth() * k, _bitmap.getHeight()
					* k);
			_matrix.postTranslate((getWidth() - _bitmap.getWidth() * k) / 2,
					(getHeight() - _bitmap.getHeight() * k) / 2);
		}

		else if (rotateDegrees == 90) {

			if (_scale != Scale.xlarge) {
				k = 1;
			} else {

				k = getWidth() * 1.0f / getHeight() < _bitmap.getHeight()
						* 1.0f / _bitmap.getWidth() * 1.0f ? getWidth() * 1.0f
						/ _bitmap.getHeight() : getHeight() * 1.0f
						/ _bitmap.getWidth();
			}

			_matrix.postScale(k, k);
			_matrix.postRotate(rotateDegrees);
			_matrix.postTranslate(_bitmap.getHeight() * k, 0);
			_matrix.postTranslate((getWidth() - _bitmap.getHeight() * k) / 2,
					(getHeight() - _bitmap.getWidth() * k) / 2);
		} else if (rotateDegrees == 270) {

			if (_scale != Scale.xlarge) {
				k = 1;
			} else {
				k = getWidth() * 1.0f / getHeight() < _bitmap.getHeight()
						* 1.0f / _bitmap.getWidth() * 1.0f ? getWidth() * 1.0f
						/ _bitmap.getHeight() : getHeight() * 1.0f
						/ _bitmap.getWidth();

			}

			_matrix.postScale(k, k);
			_matrix.postRotate(rotateDegrees);
			_matrix.postTranslate(0, _bitmap.getWidth() * k);
			_matrix.postTranslate((getWidth() - _bitmap.getHeight() * k) / 2,
					(getHeight() - _bitmap.getWidth() * k) / 2);

		}

		System.out.println("rotateDegrees=" + rotateDegrees);

		setImageMatrix(_matrix);

	}

	enum Scale {
		xlarge, large, small
	}

	Scale _scale;

	public void setImageBitmap(Bitmap bm) {
		_bitmap = bm;
		super.setImageBitmap(bm);

		if (_bitmap != null) {
			_degrees = 0;
			rotateBitMap(_degrees);
		}

	}

	private void drawSide(Canvas canvas) {
		Paint paint = new Paint();
		paint.setColor(0x99000000);
		float sideX = (getWidth() - sideWith) / 2;
		float sideY = (getHeight() - sideHeight) / 2;
		canvas.drawRect(0, 0, getWidth(), sideY, paint);
		canvas.drawRect(0, getHeight() - sideY, getWidth(), getHeight(), paint);
		canvas.drawRect(0, sideY, sideX, getHeight() - sideY, paint);
		canvas.drawRect(getWidth() - sideX, sideY, getWidth(), getHeight()
				- sideY, paint);
		paint.setColor(0xffffffff);
		canvas.drawLine(sideX, sideY, sideX + sideWith, sideY, paint);
		canvas.drawLine(sideX, sideY + sideHeight, sideX + sideWith, sideY
				+ sideHeight, paint);
		canvas.drawLine(sideX, sideY, sideX, sideY + sideHeight, paint);
		canvas.drawLine(sideX + sideWith, sideY, sideX + sideWith, sideY
				+ sideHeight, paint);
	}

	public boolean onTouch(View v, MotionEvent event) {

		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		// ���㰴��
		case MotionEvent.ACTION_DOWN:
			_savedMatrix.set(_matrix);
			prev.set(event.getX(), event.getY());
			mode = DRAG;
			break;
		// ���㰴��
		case MotionEvent.ACTION_POINTER_DOWN:
			dist = spacing(event);
			// �����������������10�����ж�Ϊ���ģʽ
			_savedMatrix.set(_matrix);
			midPoint(mid, event);
			mode = ZOOM;
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			mode = NONE;
			break;
		case MotionEvent.ACTION_MOVE:
			if (mode == DRAG) {
				_matrix.set(_savedMatrix);
				move(event.getX() - prev.x, event.getY() - prev.y);
			} else if (mode == ZOOM) {
				float newDist = spacing(event);
				_matrix.set(_savedMatrix);
				float tScale = newDist / dist;
				scale(tScale);

			}
			break;
		}
		setImageMatrix(_matrix);
		invalidate();
		// isMove();
		return true;
	}

	private void scale(float sk) {
		if (_scale == Scale.small) {
			return;
		}
		_matrix.postScale(sk, sk, mid.x, mid.y);

		fixScale();

		move(0, 0);

	}

	private void fixScale() {
		if (_bitmap == null) {
			return;
		}

		_matrix.getValues(_array);
		float curScale = Math.abs(_array[0]) + Math.abs(_array[1]);

		float minScale = 0;
		if (_degrees == 0 || _degrees == 180) {
			minScale = Math.min((float) sideWith / (float) _bitmap.getWidth(),
					(float) sideHeight / (float) _bitmap.getHeight());
		} else {
			minScale = Math.min((float) sideWith / (float) _bitmap.getHeight(),
					(float) sideHeight / (float) _bitmap.getWidth());
		}

		if (curScale < minScale) {
			if (curScale > 0) {
				double scale = minScale / curScale;
				_array[0] = (float) (_array[0] * scale);
				_array[1] = (float) (_array[1] * scale);
				_array[3] = (float) (_array[3] * scale);
				_array[4] = (float) (_array[4] * scale);
				_matrix.setValues(_array);
			}
		} else if (curScale > 1) {
			double scale = 1 / curScale;
			_array[0] = (float) (_array[0] * scale);
			_array[1] = (float) (_array[1] * scale);
			_array[3] = (float) (_array[3] * scale);
			_array[4] = (float) (_array[4] * scale);
			_matrix.setValues(_array);

		}

	}

	public void zoom() {
		if (_scale == Scale.small) {
			return;
		}

		if (_bitmap == null) {
			return;
		}
		_matrix.getValues(_array);
		float curScale = Math.abs(_array[0]) + Math.abs(_array[1]);

		if (curScale == 1) {
			return;
		}
		_matrix.postScale(1.1f, 1.1f, getWidth() / 2, getHeight() / 2);

		_matrix.getValues(_array);
		float minScale = 0;
		if (_degrees == 0 || _degrees == 180) {
			minScale = Math.min((float) sideWith / (float) _bitmap.getWidth(),
					(float) sideHeight / (float) _bitmap.getHeight());
		} else {
			minScale = Math.min((float) sideWith / (float) _bitmap.getHeight(),
					(float) sideHeight / (float) _bitmap.getWidth());
		}

		curScale = Math.abs(_array[0]) + Math.abs(_array[1]);
		if (curScale < minScale) {
			if (curScale > 0) {
				double scale = minScale / curScale;
				_array[0] = (float) (_array[0] * scale);
				_array[1] = (float) (_array[1] * scale);
				_array[3] = (float) (_array[3] * scale);
				_array[4] = (float) (_array[4] * scale);
				_matrix.setValues(_array);
			}
		} else if (curScale > 1) {
			double scale = 1 / curScale;
			_array[0] = (float) (_array[0] * scale);
			_array[1] = (float) (_array[1] * scale);
			_array[3] = (float) (_array[3] * scale);
			_array[4] = (float) (_array[4] * scale);
			_matrix.setValues(_array);

		}

		move(0, 0);

		setImageMatrix(_matrix);
		invalidate();

	}

	public void narrow() {
		if (_scale == Scale.small) {
			return;
		}
		if (_bitmap == null) {
			return;
		}
		_matrix.getValues(_array);
		float curScale = Math.abs(_array[0]) + Math.abs(_array[1]);

		float minScale = 0;
		if (_degrees == 0 || _degrees == 180) {
			minScale = Math.min((float) sideWith / (float) _bitmap.getWidth(),
					(float) sideHeight / (float) _bitmap.getHeight());
		} else {
			minScale = Math.min((float) sideWith / (float) _bitmap.getHeight(),
					(float) sideHeight / (float) _bitmap.getWidth());
		}

		if (minScale == curScale) {
			return;

		}
		_matrix.postScale(0.9f, 0.9f, getWidth() / 2, getHeight() / 2);
		_matrix.getValues(_array);
		curScale = Math.abs(_array[0]) + Math.abs(_array[1]);

		if (curScale < minScale) {
			if (curScale > 0) {
				double scale = minScale / curScale;
				_array[0] = (float) (_array[0] * scale);
				_array[1] = (float) (_array[1] * scale);
				_array[3] = (float) (_array[3] * scale);
				_array[4] = (float) (_array[4] * scale);
				_matrix.setValues(_array);
			}
		} else if (curScale > 1) {
			double scale = 1 / curScale;
			_array[0] = (float) (_array[0] * scale);
			_array[1] = (float) (_array[1] * scale);
			_array[3] = (float) (_array[3] * scale);
			_array[4] = (float) (_array[4] * scale);
			_matrix.setValues(_array);

		}
		move(0, 0);
		setImageMatrix(_matrix);
		invalidate();
	}

	private void move(float x, float y) {
		if (_bitmap == null) {
			return;
		}
		if (_scale == Scale.small) {
			return;
		}

		_matrix.postTranslate(x, y);
		_matrix.getValues(_array);

		if (_degrees == 0) {
			float sk = _array[0];
			float px = _array[2];
			float py = _array[5];
			float w = _bitmap.getWidth() * sk;
			float h = _bitmap.getHeight() * sk;

			boolean isleft = px > (getWidth() - sideWith) / 2;

			boolean isright = px + w < (getWidth() - (getWidth() - sideWith) / 2);

			boolean istop = py > (getHeight() - sideHeight) / 2;

			boolean isbuttom = py + h < (getHeight() - (getHeight() - sideHeight) / 2);

			if (w > sideWith) {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - sideWith) / 2;
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2) - w;

				}
			} else {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2) - w;
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - sideWith) / 2;

				}
			}

			if (h > sideHeight) {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (isbuttom) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2)
							- h;
					// System.out.println("istop ");
				} else if (istop) {
					_array[5] = (getHeight() - sideHeight) / 2;
					// System.out.println("isbuttom");
				}
			} else {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (istop) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2)
							- h;
					// System.out.println("istop ");
				} else if (isbuttom) {
					_array[5] = (getHeight() - sideHeight) / 2;
					// System.out.println("isbuttom");
				}

			}

			_matrix.setValues(_array);
		} else if (_degrees == 90) {

			float sk = -_array[1];
			float px = _array[2];
			float py = _array[5];
			float w = _bitmap.getHeight() * sk;
			float h = _bitmap.getWidth() * sk;
			px -= w;
			// py-=h;
			boolean isleft = px > (getWidth() - sideWith) / 2;

			boolean isright = px + w < (getWidth() - (getWidth() - sideWith) / 2);

			if (isright) {
				System.out.println("px + w=" + (px + w));

				System.out.println("right="
						+ (getWidth() - (getWidth() - sideWith) / 2));
			}

			boolean istop = py > (getHeight() - sideHeight) / 2;

			boolean isbuttom = py + h < (getHeight() - (getHeight() - sideHeight) / 2);

			if (w > sideWith) {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - sideWith) / 2 + w;
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2);
					System.out.println("isright ");
				}
			} else {

				if (isleft && isright) {
				} else if (isleft) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2);
				} else if (isright) {
					_array[2] = (getWidth() - sideWith) / 2 + w;

				}
			}

			if (h > sideHeight) {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (isbuttom) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2)
							- h;
					// System.out.println("istop ");
				} else if (istop) {
					_array[5] = (getHeight() - sideHeight) / 2;
					// System.out.println("isbuttom");
				}
			} else {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (istop) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2)
							- h;
					// System.out.println("istop ");
				} else if (isbuttom) {
					_array[5] = (getHeight() - sideHeight) / 2;
					// System.out.println("isbuttom");
				}

			}

			_matrix.setValues(_array);
		} else if (180 == _degrees) {
			float sk = -_array[0];
			float px = _array[2];
			float py = _array[5];
			float w = _bitmap.getWidth() * sk;
			float h = _bitmap.getHeight() * sk;
			px -= w;
			py -= h;
			boolean isleft = px > (getWidth() - sideWith) / 2;

			boolean isright = px + w < (getWidth() - (getWidth() - sideWith) / 2);

			boolean istop = py > (getHeight() - sideHeight) / 2;

			boolean isbuttom = py + h < (getHeight() - (getHeight() - sideHeight) / 2);

			System.out.println("left=" + (getWidth() - sideWith) / 2 + " x="
					+ px + "w=" + w);

			if (w > sideWith) {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - sideWith) / 2 + w;
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2);

				}
			} else {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2);
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - sideWith) / 2 + w;
					System.out.println("isright ");
				}
			}

			if (h > sideHeight) {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (isbuttom) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2);
					// System.out.println("istop ");
				} else if (istop) {
					_array[5] = (getHeight() - sideHeight) / 2 + h;
					// System.out.println("isbuttom");
				}
			} else {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (istop) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2);
					// System.out.println("istop ");
				} else if (isbuttom) {
					_array[5] = (getHeight() - sideHeight) / 2 + h;
					// System.out.println("isbuttom");
				}

			}

			_matrix.setValues(_array);

		} else if (270 == _degrees) {

			float sk = _array[1];
			float px = _array[2];
			float py = _array[5];
			float w = _bitmap.getHeight() * sk;
			float h = _bitmap.getWidth() * sk;
			py -= h;
			boolean isleft = px > (getWidth() - sideWith) / 2;

			boolean isright = px + w < (getWidth() - (getWidth() - sideWith) / 2);

			boolean istop = py > (getHeight() - sideHeight) / 2;

			boolean isbuttom = py + h < (getHeight() - (getHeight() - sideHeight) / 2);

			System.out.println("sk=" + sk + "left=" + (getWidth() - sideWith)
					/ 2 + " x=" + px + "w=" + w);

			if (w > sideWith) {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - sideWith) / 2;
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2) - w;

				}
			} else {

				if (isleft && isright) {
					System.out.println("isleft && isright");
				} else if (isleft) {
					_array[2] = (getWidth() - (getWidth() - sideWith) / 2) - w;
					System.out.println("isleft ");
				} else if (isright) {
					_array[2] = (getWidth() - sideWith) / 2;

				}
			}

			if (h > sideHeight) {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (isbuttom) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2)
							- h;
					// System.out.println("istop ");
				} else if (istop) {
					_array[5] = (getHeight() - sideHeight) / 2;
					// System.out.println("isbuttom");
				}
			} else {
				if (istop && isbuttom) {
					// System.out.println("istop && isbuttom");
				} else if (istop) {
					_array[5] = (getHeight() - (getHeight() - sideHeight) / 2);

					// System.out.println("istop ");
				} else if (isbuttom) {
					_array[5] = (getHeight() - sideHeight) / 2 + h;
					// System.out.println("isbuttom");
				}

			}

			_matrix.setValues(_array);
		}

	}

	float[] _array = new float[9];

	@SuppressLint("FloatMath")
	private float spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	private void midPoint(PointF point, MotionEvent event) {
		float x = event.getX(0) + event.getX(1);
		float y = event.getY(0) + event.getY(1);
		point.set(x / 2, y / 2);
	}

	int _degrees = 0;

	public void rotateDegrees(int degrees) {

		if (degrees < 0) {
			degrees = 360 - degrees;
		}
		_degrees += degrees;
		_degrees %= 360;

		rotateBitMap(_degrees);

		invalidate();

	}

	Bitmap _bufferBitmap;

	public void reset() {
		setImageBitmap(null);
		if (_bitmap != null) {
			_bitmap.recycle();
			_bitmap = null;
		}

		if (_bufferBitmap != null) {
			_bufferBitmap.recycle();
			_bufferBitmap = null;
		}
		_degrees = 0;

	}

	public Bitmap getEidtedBitmap() {

		if (_bitmap == null) {
			return null;
		}

		int offsetLeft = (getWidth() - sideWith) / 2;
		int offsetTop = (getHeight() - sideHeight) / 2;
		int offsetRight = getWidth() - offsetLeft;
		int offsetButtom = getHeight() - offsetTop;

		RectF rectF = new RectF(0, 0, _bitmap.getWidth(), _bitmap.getHeight());

		_matrix.mapRect(rectF);
		System.out.println(rectF.toString());
		float top, left, right, buttom;

		if (offsetTop > rectF.top) {
			top = offsetTop;
		} else {
			top = rectF.top;
		}

		if (offsetLeft > rectF.left) {

			left = offsetLeft;
		} else {
			left = rectF.left;
		}

		if (offsetButtom > rectF.bottom) {
			buttom = rectF.bottom;
		} else {
			buttom = offsetButtom;
		}

		if (offsetRight > rectF.right) {
			right = rectF.right;
		} else {
			right = offsetRight;
		}

		rectF.top = top;
		rectF.left = left;
		rectF.right = right;
		rectF.bottom = buttom;

		System.out.println(rectF.toString());

		Matrix inverse = new Matrix();

		boolean isinverse = _matrix.invert(inverse);
		System.out.println("��ȡ�������" + isinverse);

		inverse.mapRect(rectF);
		System.out.println(rectF.toString());
		return Bitmap.createBitmap(_bitmap, (int) rectF.left, (int) rectF.top,
				(int) (rectF.right - rectF.left),
				(int) (rectF.bottom - rectF.top), _matrix, true);

	}
}
